package com.xiashitech.apiservice.api;

import cn.hutool.json.JSONUtil;
import com.xiashitech.apiservice.allmem.DbMemManager;
import com.xiashitech.apiservice.config.AuthConfig;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;

@Controller
@RequestMapping(value = "/v1/agent")
@RequiredArgsConstructor(onConstructor =@_(@Autowired))
public class AuthFactCacheController {
    private final AuthConfig authConfig;
    private final DbMemManager dbMemManager;
    @RequestMapping(value = "/updateAuthFactCache", method = RequestMethod.GET)
    @ResponseBody
    public String updateAuthFactCache() {
        dbMemManager.setUpdatecache(1);
        return "";
    }
    @RequestMapping(value = "/authFactCacheStatus", method = RequestMethod.GET)
    @ResponseBody
    public String authFactCacheStatus() {
        String cmd = "要求更新";
        if(dbMemManager.getUpdatecache() == 0) {
            cmd = "没要求更新";
        }
        String statusName = "更新完成";
        if(dbMemManager.getCacheupdating() == 1) {
            statusName = "更新中";
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime ldtStart = new Date(dbMemManager.getCacheStartMillis()).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
        LocalDateTime ldtComplete = new Date(dbMemManager.getCacheCompleteMillis()).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();

        String resp = String.format("当前 %s, 缓存更新状态：%s，更新开始时间：%s, 更新完成时间：%s，耗时(ms)：%d，当前启用全量内存: %s, size: %s, %s",
                cmd,
                statusName,
                ldtStart.format(formatter),
                ldtComplete.format(formatter),
                dbMemManager.getCacheCompleteMillis() - dbMemManager.getCacheStartMillis(),
                authConfig.isUseAllAuthInMemory(),
                dbMemManager.getDbInfoInMemory().getUserAuthTableMap().size(),
                dbMemManager.getDbInfoInMemory().getTableIdMap().size());
        StringBuilder sb = new StringBuilder();
        sb.append(resp).append("\n");
        sb.append("Service count is: ").append(dbMemManager.getDbInfoInMemory().getMetaDataDBServices().size()).append(", they are: ");
        dbMemManager.getDbInfoInMemory().getMetaDataDBServices().stream().forEach(service->sb.append(service.getName()).append(","));
        sb.append("\n");
        sb.append("MetaDataDB count is: ").append(dbMemManager.getDbInfoInMemory().getMetaDataDBS().size()).append(", they are: ");
        dbMemManager.getDbInfoInMemory().getMetaDataDBS().stream().forEach(db->sb.append(db.getName()).append(","));
        sb.append("\n");
        sb.append("What exits authInfo tables or columns is: \n");
        AtomicInteger authTabColCnt = new AtomicInteger(0);
        AtomicInteger authTabCnt = new AtomicInteger(0);
        AtomicInteger colCnt = new AtomicInteger(0);
        AtomicInteger authColCnt = new AtomicInteger(0);
        dbMemManager.getDbInfoInMemory().getUserAuthTableMap().entrySet().stream().forEach(entry->{
            if(entry.getValue() != null ) {
                if(entry.getValue().getTabAuth()) {
                    authTabCnt.incrementAndGet();
                    sb.append("table key: ").append(entry.getKey()).append(", ").append(entry.getValue().getTabAuthReason());
                    StringBuilder sbCol = new StringBuilder();
                    entry.getValue().getColumns().stream().forEach(column -> {
                        colCnt.incrementAndGet();
                        if(column.getColAuth()) {
                            authColCnt.incrementAndGet();
                            authTabColCnt.incrementAndGet();
                            sbCol.append(column.getColName()).append(":").append(column.getColAuthReason()).append(",");
                        }
                    });
                    if(sbCol.length()>0) {
                        sb.append(", its authColumn are: ").append(sbCol);
                    }
                    sb.append("\n");
                } else {
                    StringBuilder sbCol = new StringBuilder();
                    entry.getValue().getColumns().stream().forEach(column -> {
                        colCnt.incrementAndGet();
                        if(column.getColAuth()) {
                            authColCnt.incrementAndGet();
                            sbCol.append(column.getColName()).append(":").append(column.getColAuthReason()).append(",");
                        }
                    });
                    if(sbCol.length()>0) {
                        sb.append("table key: ").append(entry.getKey()).append(", table is not authed but column, its authColumn are: ").append(sbCol).append("\n");
                    }
                }
            }
        });
        sb.append("\n");
        sb.append("table count tc/t/a: ").append(authTabColCnt.get()).append("/").append(authTabCnt.get()).append("/").append(dbMemManager.getDbInfoInMemory().getUserAuthTableMap().size()).append("\n")
                .append("  total authed col/total col: ").append(authColCnt.get()).append('/').append(colCnt.get()).append("\n");
        return sb.toString();
    }
}
